﻿/*
<File>
	<Copyright>Copyright © 2007, Daniel Vaughan. All rights reserved.</Copyright>
	<License see="//License.txt"/>
	<Owner Name="Daniel Vaughan" Email="danielvaughan@outcoder.com"/>
	<CreationDate>2007/11/27 12:44</CreationDate>
	<LastSubmissionDate>$Date: $</LastSubmissionDate>
	<Version>$Revision: $</Version>
</File>
*/

using System;
using System.Configuration;

namespace DanielVaughan.Logging.Filters
{
	/// <summary>
	/// This filter compares checks that the current
	/// date and time is between the range specified 
	/// in the configuration. 
	/// </summary>
	class TimeRangeFilter : FilterBase
	{
		string beginConfig;
		string endConfig;

		public TimeRangeFilter()
		{
			Init += TimeRangeFilter_Init;
		}

		void TimeRangeFilter_Init(object sender, FilterInitEventArgs e)
		{
			ArgumentValidator.AssertNotNull(e, "e");
			ArgumentValidator.AssertNotNull(e.ConfigurationElement, "e.ConfigurationElement");

			/* Reset state. */
			beginConfig = endConfig = null;

			/* TODO: put in util. */
			var beginAttribute = e.ConfigurationElement.Attributes["Begin"];
			if (beginAttribute == null)
			{
				throw new ClientLoggingException("Begin ip address attribute does not exists."); /* TODO: Make localizable resource. */
			}
			beginConfig = beginAttribute.Value;

			var endAttribute = e.ConfigurationElement.Attributes["End"];
			if (endAttribute == null)
			{
				throw new ClientLoggingException("End ip address attribute does not exists."); /* TODO: Make localizable resource. */
			}
			endConfig = endAttribute.Value;

			try
			{
				DateTime.Parse(beginConfig);
			}
			catch (FormatException ex)
			{
				throw new ClientLoggingException("begin time is invalid. " + beginConfig, ex);
			}

			try
			{
				DateTime.Parse(endConfig);
			}
			catch (FormatException ex)
			{
				throw new ClientLoggingException("end time is invalid. " + endConfig, ex);
			}

			if (Action == FilterAction.Default)
			{
				Action = FilterAction.Allow;
			}

			if (Action != FilterAction.Allow && Action != FilterAction.Deny)
			{
				throw new ConfigurationErrorsException(InvalidActionMessage);
			}
		}

		public override bool IsValid(LogEntryOrigin origin, IClientInfo info)
		{
			/* We should enhance this class to allow for 
			 testing of the current time without reparsing
			 the begin and end time value. This would require
			 that we implement a format that allows us to 
			 specify non intra-day timespans. E.g. 11pm to 13pm. */
			DateTime beginTime = DateTime.Parse(beginConfig);
			DateTime endTime = DateTime.Parse(endConfig);
			DateTime now = DateTime.Now;
			bool withinRange = beginTime <= now && now < endTime;

			switch (Action)
			{
				case FilterAction.Allow:
					return withinRange;
				case FilterAction.Deny:
					return !withinRange;
			}
			throw new ConfigurationErrorsException(InvalidActionMessage);
		}
	}
}
